#include "ParseNodes.h"
#include "DFA.h"

#include <stdlib.h>
#include <sstream>
#include <queue>

using namespace std;

extern const char *escapedCharacterDFA;

/* CONVERTS */
ParentNode* ParseNode::Convert(ParentNode *n) { return n;  }
LeafNode* ParseNode::Convert(LeafNode *n) { return n; }

ParentNode* CompilationUnitNode::Convert(ParentNode *p) {
	CompilationUnitNode *n = new CompilationUnitNode();
	n->children = p->children;
	return n;
}
ParentNode* PackageDeclarationNode::Convert(ParentNode *p) {
	PackageDeclarationNode *n = new PackageDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* ImportDeclarationsNode::Convert(ParentNode *p) {
	ImportDeclarationsNode *n = new ImportDeclarationsNode();
	n->children = p->children;
	return n;
}
ParentNode* ImportDeclarationNode::Convert(ParentNode *p) {
	ImportDeclarationNode *n = new ImportDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* SingleTypeImportDeclarationNode::Convert(ParentNode *p) {
	SingleTypeImportDeclarationNode *n = new SingleTypeImportDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* TypeImportOnDemandDeclarationNode::Convert(ParentNode *p) {
	TypeImportOnDemandDeclarationNode *n = new TypeImportOnDemandDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* TypeDeclarationNode::Convert(ParentNode *p) {
	TypeDeclarationNode *n = new TypeDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassDeclarationNode::Convert(ParentNode *p) {
	ClassDeclarationNode *n = new ClassDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* ModifiersNode::Convert(ParentNode *p) {
	ModifiersNode *n = new ModifiersNode();
	n->children = p->children;
	return n;
}
ParentNode* ModifierNode::Convert(ParentNode *p) {
	ModifierNode *n = new ModifierNode();
	n->children = p->children;
	return n;
}
ParentNode* SuperNode::Convert(ParentNode *p) {
	SuperNode *n = new SuperNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfacesNode::Convert(ParentNode *p) {
	InterfacesNode *n = new InterfacesNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfaceTypeListNode::Convert(ParentNode *p) {
	InterfaceTypeListNode *n = new InterfaceTypeListNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassBodyNode::Convert(ParentNode *p) {
	ClassBodyNode *n = new ClassBodyNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassBodyDeclarationsNode::Convert(ParentNode *p) {
	ClassBodyDeclarationsNode *n = new ClassBodyDeclarationsNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassBodyDeclarationNode::Convert(ParentNode *p) {
	ClassBodyDeclarationNode *n = new ClassBodyDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassMemberDeclarationNode::Convert(ParentNode *p) {
	ClassMemberDeclarationNode *n = new ClassMemberDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* FieldDeclarationNode::Convert(ParentNode *p) {
	FieldDeclarationNode *n = new FieldDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* VariableDeclaratorNode::Convert(ParentNode *p) {
	VariableDeclaratorNode *n = new VariableDeclaratorNode();
	n->children = p->children;
	return n;
}
ParentNode* VariableInitializerNode::Convert(ParentNode *p) {
	VariableInitializerNode *n = new VariableInitializerNode();
	n->children = p->children;
	return n;
}
ParentNode* MethodDeclarationNode::Convert(ParentNode *p) {
	MethodDeclarationNode *n = new MethodDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* MethodHeaderNode::Convert(ParentNode *p) {
	MethodHeaderNode *n = new MethodHeaderNode();
	n->children = p->children;
	return n;
}
ParentNode* MethodDeclaratorNode::Convert(ParentNode *p) {
	MethodDeclaratorNode *n = new MethodDeclaratorNode();
	n->children = p->children;
	return n;
}
ParentNode* FormalParameterListNode::Convert(ParentNode *p) {
	FormalParameterListNode *n = new FormalParameterListNode();
	n->children = p->children;
	return n;
}
ParentNode* FormalParameterNode::Convert(ParentNode *p) {
	FormalParameterNode *n = new FormalParameterNode();
	n->children = p->children;
	return n;
}
ParentNode* MethodBodyNode::Convert(ParentNode *p) {
	MethodBodyNode *n = new MethodBodyNode();
	n->children = p->children;
	return n;
}
ParentNode* ConstructorDeclarationNode::Convert(ParentNode *p) {
	ConstructorDeclarationNode *n = new ConstructorDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* ConstructorDeclaratorNode::Convert(ParentNode *p) {
	ConstructorDeclaratorNode *n = new ConstructorDeclaratorNode();
	n->children = p->children;
	return n;
}
ParentNode* ConstructorBodyNode::Convert(ParentNode *p) {
	ConstructorBodyNode *n = new ConstructorBodyNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfaceDeclarationNode::Convert(ParentNode *p) {
	InterfaceDeclarationNode *n = new InterfaceDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* ExtendsInterfacesNode::Convert(ParentNode *p) {
	ExtendsInterfacesNode *n = new ExtendsInterfacesNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfaceBodyNode::Convert(ParentNode *p) {
	InterfaceBodyNode *n = new InterfaceBodyNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfaceMemberDeclarationsNode::Convert(ParentNode *p) {
	InterfaceMemberDeclarationsNode *n = new InterfaceMemberDeclarationsNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfaceMemberDeclarationNode::Convert(ParentNode *p) {
	InterfaceMemberDeclarationNode *n = new InterfaceMemberDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* AbstractMethodDeclarationNode::Convert(ParentNode *p) {
	AbstractMethodDeclarationNode *n = new AbstractMethodDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* BlockNode::Convert(ParentNode *p) {
	BlockNode *n = new BlockNode();
	n->children = p->children;
	return n;
}
ParentNode* BlockStatementsNode::Convert(ParentNode *p) {
	BlockStatementsNode *n = new BlockStatementsNode();
	n->children = p->children;
	return n;
}
ParentNode* BlockStatementNode::Convert(ParentNode *p) {
	BlockStatementNode *n = new BlockStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* LocalVariableDeclarationStatementNode::Convert(ParentNode *p) {
	LocalVariableDeclarationStatementNode *n = new LocalVariableDeclarationStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* LocalVariableDeclarationNode::Convert(ParentNode *p) {
	LocalVariableDeclarationNode *n = new LocalVariableDeclarationNode();
	n->children = p->children;
	return n;
}
ParentNode* StatementNode::Convert(ParentNode *p) {
	StatementNode *n = new StatementNode();
	n->children = p->children;
	return n;
}
ParentNode* StatementNoShortIfNode::Convert(ParentNode *p) {
	StatementNoShortIfNode *n = new StatementNoShortIfNode();
	n->children = p->children;
	return n;
}
ParentNode* StatementWithoutTrailingSubstatementNode::Convert(ParentNode *p) {
	StatementWithoutTrailingSubstatementNode *n = new StatementWithoutTrailingSubstatementNode();
	n->children = p->children;
	return n;
}
ParentNode* EmptyStatementNode::Convert(ParentNode *p) {
	EmptyStatementNode *n = new EmptyStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* ExpressionStatementNode::Convert(ParentNode *p) {
	ExpressionStatementNode *n = new ExpressionStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* StatementExpressionNode::Convert(ParentNode *p) {
	StatementExpressionNode *n = new StatementExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* IfStatementNode::Convert(ParentNode *p) {
	IfStatementNode *n = new IfStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* IfThenStatementNode::Convert(ParentNode *p) {
	IfThenStatementNode *n = new IfThenStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* IfThenElseStatementNode::Convert(ParentNode *p) {
	IfThenElseStatementNode *n = new IfThenElseStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* IfThenElseStatementNoShortIfNode::Convert(ParentNode *p) {
	IfThenElseStatementNoShortIfNode *n = new IfThenElseStatementNoShortIfNode();
	n->children = p->children;
	return n;
}
ParentNode* WhileStatementNode::Convert(ParentNode *p) {
	WhileStatementNode *n = new WhileStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* WhileStatementNoShortIfNode::Convert(ParentNode *p) {
	WhileStatementNoShortIfNode *n = new WhileStatementNoShortIfNode();
	n->children = p->children;
	return n;
}
ParentNode* ForStatementNode::Convert(ParentNode *p) {
	ForStatementNode *n = new ForStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* ForStatementNoShortIfNode::Convert(ParentNode *p) {
	ForStatementNoShortIfNode *n = new ForStatementNoShortIfNode();
	n->children = p->children;
	return n;
}
ParentNode* ForInitNode::Convert(ParentNode *p) {
	ForInitNode *n = new ForInitNode();
	n->children = p->children;
	return n;
}
ParentNode* ForUpdateNode::Convert(ParentNode *p) {
	ForUpdateNode *n = new ForUpdateNode();
	n->children = p->children;
	return n;
}
ParentNode* ReturnStatementNode::Convert(ParentNode *p) {
	ReturnStatementNode *n = new ReturnStatementNode();
	n->children = p->children;
	return n;
}
ParentNode* PrimaryNode::Convert(ParentNode *p) {
	PrimaryNode *n = new PrimaryNode();
	n->children = p->children;
	return n;
}
ParentNode* PrimaryNoNewArrayNode::Convert(ParentNode *p) {
	PrimaryNoNewArrayNode *n = new PrimaryNoNewArrayNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassInstanceCreationExpressionNode::Convert(ParentNode *p) {
	ClassInstanceCreationExpressionNode *n = new ClassInstanceCreationExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassInstanceCreationExpressionWithoutArgumentsNode::Convert(ParentNode *p) {
	ClassInstanceCreationExpressionWithoutArgumentsNode *n = new ClassInstanceCreationExpressionWithoutArgumentsNode();
	n->children = p->children;
	return n;
}
ParentNode* ArgumentListNode::Convert(ParentNode *p) {
	ArgumentListNode *n = new ArgumentListNode();
	n->children = p->children;
	return n;
}
ParentNode* ArrayCreationExpressionNode::Convert(ParentNode *p) {
	ArrayCreationExpressionNode *n = new ArrayCreationExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* DimExprNode::Convert(ParentNode *p) {
	DimExprNode *n = new DimExprNode();
	n->children = p->children;
	return n;
}
ParentNode* FieldAccessNode::Convert(ParentNode *p) {
	FieldAccessNode *n = new FieldAccessNode();
	n->children = p->children;
	return n;
}
ParentNode* MethodInvocationNode::Convert(ParentNode *p) {
	MethodInvocationNode *n = new MethodInvocationNode();
	n->children = p->children;
	return n;
}
ParentNode* MethodInvocationWithoutArgumentsNode::Convert(ParentNode *p) {
	MethodInvocationWithoutArgumentsNode *n = new MethodInvocationWithoutArgumentsNode();
	n->children = p->children;
	return n;
}
ParentNode* ArrayAccessNode::Convert(ParentNode *p) {
	ArrayAccessNode *n = new ArrayAccessNode();
	n->children = p->children;
	return n;
}
ParentNode* ExpressionNode::Convert(ParentNode *p) {
	ExpressionNode *n = new ExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* AssignmentNode::Convert(ParentNode *p) {
	AssignmentNode *n = new AssignmentNode();
	n->children = p->children;
	return n;
}
ParentNode* LeftHandSideNode::Convert(ParentNode *p) {
	LeftHandSideNode *n = new LeftHandSideNode();
	n->children = p->children;
	return n;
}
ParentNode* BinaryOperatorExpressionNode::Convert(ParentNode *p) {
	BinaryOperatorExpressionNode *n = new BinaryOperatorExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* ConditionalOrExpressionNode::Convert(ParentNode *p) {
	ConditionalOrExpressionNode *n = new ConditionalOrExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* ConditionalAndExpressionNode::Convert(ParentNode *p) {
	ConditionalAndExpressionNode *n = new ConditionalAndExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* InclusiveOrExpressionNode::Convert(ParentNode *p) {
	InclusiveOrExpressionNode *n = new InclusiveOrExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* ExclusiveOrExpressionNode::Convert(ParentNode *p) {
	ExclusiveOrExpressionNode *n = new ExclusiveOrExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* AndExpressionNode::Convert(ParentNode *p) {
	AndExpressionNode *n = new AndExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* EqualityExpressionNode::Convert(ParentNode *p) {
	EqualityExpressionNode *n = new EqualityExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* RelationalExpressionNode::Convert(ParentNode *p) {
	RelationalExpressionNode *n = new RelationalExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* AdditiveExpressionNode::Convert(ParentNode *p) {
	AdditiveExpressionNode *n = new AdditiveExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* MultiplicativeExpressionNode::Convert(ParentNode *p) {
	MultiplicativeExpressionNode *n = new MultiplicativeExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* UnaryExpressionNode::Convert(ParentNode *p) {
	UnaryExpressionNode *n = new UnaryExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* UnaryExpressionNotPlusMinusNode::Convert(ParentNode *p) {
	UnaryExpressionNotPlusMinusNode *n = new UnaryExpressionNotPlusMinusNode();
	n->children = p->children;
	return n;
}
ParentNode* PostfixExpressionNode::Convert(ParentNode *p) {
	PostfixExpressionNode *n = new PostfixExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* CastExpressionNode::Convert(ParentNode *p) {
	CastExpressionNode *n = new CastExpressionNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassTypeNode::Convert(ParentNode *p) {
	ClassTypeNode *n = new ClassTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* InterfaceTypeNode::Convert(ParentNode *p) {
	InterfaceTypeNode *n = new InterfaceTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* TypeNode::Convert(ParentNode *p) {
	TypeNode *n = new TypeNode();
	n->children = p->children;
	return n;
}
ParentNode* PrimitiveTypeNode::Convert(ParentNode *p) {
	PrimitiveTypeNode *n = new PrimitiveTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* NumericTypeNode::Convert(ParentNode *p) {
	NumericTypeNode *n = new NumericTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* IntegralTypeNode::Convert(ParentNode *p) {
	IntegralTypeNode *n = new IntegralTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* ReferenceTypeNode::Convert(ParentNode *p) {
	ReferenceTypeNode *n = new ReferenceTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* ClassOrInterfaceTypeNode::Convert(ParentNode *p) {
	ClassOrInterfaceTypeNode *n = new ClassOrInterfaceTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* ArrayTypeNode::Convert(ParentNode *p) {
	ArrayTypeNode *n = new ArrayTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* PrimitiveArrayTypeNode::Convert(ParentNode *p) {
	PrimitiveArrayTypeNode *n = new PrimitiveArrayTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* ObjectArrayTypeNode::Convert(ParentNode *p) {
	ObjectArrayTypeNode *n = new ObjectArrayTypeNode();
	n->children = p->children;
	return n;
}
ParentNode* NameNode::Convert(ParentNode *p) {
	NameNode *n = new NameNode();
	n->children = p->children;
	return n;
}
ParentNode* SimpleNameNode::Convert(ParentNode *p) {
	SimpleNameNode *n = new SimpleNameNode();
	n->children = p->children;
	return n;
}
ParentNode* QualifiedNameNode::Convert(ParentNode *p) {
	QualifiedNameNode *n = new QualifiedNameNode();
	n->children = p->children;
	return n;
}
ParentNode* LiteralNode::Convert(ParentNode *p) {
	LiteralNode *n = new LiteralNode();
	n->children = p->children;
	return n;
}
ParentNode* IntegerLiteralNode::Convert(ParentNode *p) {
	IntegerLiteralNode *l = new IntegerLiteralNode();
	l->children.shrink_to_fit();
	string v = ((LeafNode*)(*p)[0]())->lexeme;

	stringstream ss;
	ss << v;
	ss >> l->value;

	return l;
}
ParentNode* BooleanLiteralNode::Convert(ParentNode *p) {
	BooleanLiteralNode *l = new BooleanLiteralNode();
	l->children.shrink_to_fit();
	l->value = (((LeafNode*)(*p)[0]())->lexeme == "true");
	return l;
}
ParentNode* StringLiteralNode::Convert(ParentNode *p) {
	static DFA unescapeCharDfa(escapedCharacterDFA);

	StringLiteralNode *l = new StringLiteralNode();
	l->children.shrink_to_fit();

	string &lex = ((LeafNode*)(*p)[0]())->lexeme;
	lex = lex.substr(1, lex.length() - 2);

	//Unescape any escaped characters
	l->value = string();
	for (unsigned int i = 0; i < lex.length();) {
		if (lex[i] != '\\') {
			l->value += lex[i++];
			continue;
		}

		unescapeCharDfa.Reset();
		string value;
		for (++i; i < lex.length() && unescapeCharDfa.TransitionOn(string(1, lex[i])); ++i) value += lex[i];

		if (unescapeCharDfa.CurrentStateName().front() != 'o') value = unescapeCharDfa.CurrentStateName();

		l->value += (unsigned char)strtoul(value.c_str(), NULL, 8);
	}
	return l;
}
ParentNode* CharacterLiteralNode::Convert(ParentNode *p) {
	CharacterLiteralNode *l = new CharacterLiteralNode();
	l->children.shrink_to_fit();
	//A character is really just a short string, right?
	l->value = ((StringLiteralNode*)StringLiteralNode().Convert(p))->value.front();

	return l;
}
ParentNode* NullLiteralNode::Convert(ParentNode *p) {
	NullLiteralNode *n = new NullLiteralNode();
	n->children = p->children;
	return n;
}


